import tkinter as tk
from tkinter import ttk
import psutil
import threading
import time
import socket
from http.server import HTTPServer, BaseHTTPRequestHandler


# ==================
# 监控数据收集模块
# ==================
class SystemMonitor:
    def __init__(self):
        self.data = {
            'cpu_percent': 0.0,
            'mem_total': 0,
            'mem_used': 0,
            'disk_total': 0,
            'disk_used': 0,
            'net_sent': 0,
            'net_recv': 0
        }
        self.last_net_io = psutil.net_io_counters()
        self.running = True

    def collect_metrics(self):
        while self.running:
            # CPU 使用率
            self.data['cpu_percent'] = psutil.cpu_percent(interval=1)

            # 内存使用
            mem = psutil.virtual_memory()
            self.data['mem_total'] = mem.total
            self.data['mem_used'] = mem.used

            # 磁盘使用 (C盘)
            disk = psutil.disk_usage('C:\\')
            self.data['disk_total'] = disk.total
            self.data['disk_used'] = disk.used

            # 网络流量
            net_io = psutil.net_io_counters()
            self.data['net_sent'] = net_io.bytes_sent - self.last_net_io.bytes_sent
            self.data['net_recv'] = net_io.bytes_recv - self.last_net_io.bytes_recv
            self.last_net_io = net_io

            time.sleep(1)

    def start(self):
        self.thread = threading.Thread(target=self.collect_metrics, daemon=True)
        self.thread.start()

    def stop(self):
        self.running = False


# ==================
# HTTP 指标导出器
# ==================
class MetricsHandler(BaseHTTPRequestHandler):
    monitor = None

    def do_GET(self):
        if self.path == '/metrics':
            self.send_response(200)
            self.send_header('Content-type', 'text/plain')
            self.end_headers()

            metrics = f"""# HELP cpu_usage CPU usage percentage
# TYPE cpu_usage gauge
cpu_usage {self.monitor.data['cpu_percent']}

# HELP memory_used Memory used in bytes
# TYPE memory_used gauge
memory_used {self.monitor.data['mem_used']}

# HELP memory_total Total memory in bytes
# TYPE memory_total gauge
memory_total {self.monitor.data['mem_total']}

# HELP disk_used Disk space used in bytes
# TYPE disk_used gauge
disk_used {self.monitor.data['disk_used']}

# HELP disk_total Total disk space in bytes
# TYPE disk_total gauge
disk_total {self.monitor.data['disk_total']}

# HELP network_sent_bytes Network bytes sent
# TYPE network_sent_bytes counter
network_sent_bytes {self.monitor.data['net_sent']}

# HELP network_received_bytes Network bytes received
# TYPE network_received_bytes counter
network_received_bytes {self.monitor.data['net_recv']}
"""
            self.wfile.write(metrics.encode())
        else:
            self.send_response(404)
            self.end_headers()


# ==================
# GUI 界面
# ==================
class MonitorApp:
    def __init__(self, root, monitor):
        self.root = root
        self.monitor = monitor
        root.title("Prometheus Node Exporter for Windows ")
        root.geometry("400x300")

        # 设置样式
        style = ttk.Style()
        style.configure("TLabel", font=("Arial", 10))
        style.configure("Title.TLabel", font=("Arial", 12, "bold"))

        # 创建标签框架
        frame = ttk.Frame(root, padding="10")
        frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        ttk.Label(frame, text="Windows 系统监控", style="Title.TLabel").grid(row=0, column=0, columnspan=2, pady=10)

        # CPU 指标
        ttk.Label(frame, text="CPU 使用率:").grid(row=1, column=0, sticky=tk.W)
        self.cpu_var = tk.StringVar()
        ttk.Label(frame, textvariable=self.cpu_var).grid(row=1, column=1, sticky=tk.E)

        # 内存指标
        ttk.Label(frame, text="内存使用:").grid(row=2, column=0, sticky=tk.W)
        self.mem_var = tk.StringVar()
        ttk.Label(frame, textvariable=self.mem_var).grid(row=2, column=1, sticky=tk.E)

        # 磁盘指标
        ttk.Label(frame, text="磁盘使用 (C:):").grid(row=3, column=0, sticky=tk.W)
        self.disk_var = tk.StringVar()
        ttk.Label(frame, textvariable=self.disk_var).grid(row=3, column=1, sticky=tk.E)

        # 网络指标
        ttk.Label(frame, text="网络发送:").grid(row=4, column=0, sticky=tk.W)
        self.net_sent_var = tk.StringVar()
        ttk.Label(frame, textvariable=self.net_sent_var).grid(row=4, column=1, sticky=tk.E)

        ttk.Label(frame, text="网络接收:").grid(row=5, column=0, sticky=tk.W)
        self.net_recv_var = tk.StringVar()
        ttk.Label(frame, textvariable=self.net_recv_var).grid(row=5, column=1, sticky=tk.E)

        # 状态信息
        self.status_var = tk.StringVar()
        self.status_var_ip = tk.StringVar()
        self.status_var.set("监控运行中...")
        ttk.Label(frame, textvariable=self.status_var).grid(row=8, column=0, columnspan=2, pady=10)
        ttk.Label(frame, textvariable=self.status_var_ip).grid(row=6, column=0, columnspan=2, pady=10)
        # 退出按钮
        ttk.Button(frame, text="退出", command=self.on_exit).grid(row=7, column=0, columnspan=2, pady=10)

        # 启动UI更新
        self.update_ui()

    def format_bytes(self, size):
        # 简化字节显示
        for unit in ['B', 'KB', 'MB', 'GB']:
            if size < 1024:
                return f"{size:.2f} {unit}"
            size /= 1024
        return f"{size:.2f} TB"

    def update_ui(self):
        data = self.monitor.data
        self.cpu_var.set(f"{data['cpu_percent']:.1f}%")
        self.mem_var.set(f"{self.format_bytes(data['mem_used'])} / {self.format_bytes(data['mem_total'])}")
        self.disk_var.set(f"{self.format_bytes(data['disk_used'])} / {self.format_bytes(data['disk_total'])}")
        self.net_sent_var.set(self.format_bytes(data['net_sent']))
        self.net_recv_var.set(self.format_bytes(data['net_recv']))

        self.root.after(1000, self.update_ui)  # 每秒更新

    def on_exit(self):
        self.monitor.stop()
        self.root.destroy()


# ==================
# 主程序
# ==================
if __name__ == "__main__":
    # 创建监控器
    monitor = SystemMonitor()
    monitor.start()

    # 设置HTTP处理器的监控实例
    MetricsHandler.monitor = monitor

    # 启动HTTP服务器（在后台线程）
    httpd = HTTPServer(('0.0.0.0', 9100), MetricsHandler)
    server_thread = threading.Thread(target=httpd.serve_forever, daemon=True)
    server_thread.start()

    # 获取本机IP
    hostname = socket.gethostname()
    ip_address = socket.gethostbyname(hostname)

    # 启动GUI
    root = tk.Tk()
    app = MonitorApp(root, monitor)
    app.status_var_ip.set(f"本机IP:{ip_address}")
    # 显示监控地址
    app.status_var.set(f"接口地址: http://{ip_address}:9100/metrics")

    root.mainloop()

    # 关闭HTTP服务器
    httpd.shutdown()
    server_thread.join()